Skip to content

Conversation

@0xZRA
Copy link
Contributor

@0xZRA 0xZRA commented Apr 25, 2025

Closes #611

I decided to follow existing pattern of TargetContracts and TargetContractsBalances sequential deployments. I think the core functionality is in place (and I hope it meets the requirements?), but the PR could be improved with more edge case testing.

@anishnaik @montyly please let me know your thoughts whenever you get a chance

@0xZRA 0xZRA changed the title [WIP]: Allow Medusa to run init function (ex: setUp) once per fuzz run Allow Medusa to run init function (ex: setUp) once per fuzz run Apr 28, 2025
@0xZRA 0xZRA marked this pull request as ready for review April 28, 2025 12:25
@anishnaik
Copy link
Collaborator

@0xZRA appreciate the quick turnaround! I need a few days before I can get to reviewing it just FYI :)

@0xZRA
Copy link
Contributor Author

0xZRA commented Apr 28, 2025

@0xZRA appreciate the quick turnaround! I need a few days before I can get to reviewing it just FYI :)

Absolutely! And thanks for the opportunity ;)

@montyly
Copy link
Contributor

montyly commented Jul 7, 2025

My bad, I never noticed the progression on this PR. This is great thanks @0xZRA. I tested it on a larger codebase and it works

In term of usability, I am wondering it would make sense to add a flag to enable setUp() to be called by default on all the contract that implements it?

@montyly montyly mentioned this pull request Jul 7, 2025
@0xZRA
Copy link
Contributor Author

0xZRA commented Jul 7, 2025

@montyly Thanks for your feedback! I can work on adding the flag, it may take me few days though

@CLAassistant
Copy link

CLAassistant commented Jul 8, 2025

CLA assistant check
All committers have signed the CLA.

@0xZRA
Copy link
Contributor Author

0xZRA commented Jul 8, 2025

@montyly Let me know if the latest commit delivers the intended improvement to devx. My assumption is that the default configuration values will still be processed downstream to address all contracts that implement it.
I couldn't find the test that covers flags so maybe it's a good opportunity to add it?

@montyly
Copy link
Contributor

montyly commented Jul 9, 2025

thanks for the quick work!

To be honest I would even go further, and have the flag <name> skip targetContractsInitFunctions and just enable setUp(). The flag name could be enableFoundrySetUp or something like that?

The reasoning is that all the foundry-based projects uses a setUp() function, so I think its fair to assume a majority of users just need the setUp for the init functions

@0xZRA
Copy link
Contributor Author

0xZRA commented Jul 9, 2025

@montyly let me know if the latest approach works.
I also added the UseInitFunctions to control whether init functions (via use-init-fns or enable-foundry-setup) should be processed at all.
Since you mentioned that the main functionality seemed to be working as expected, the initialization logic hasn't changed, it's just now controlled by the feature flag.

My main concern is the number of changes to fuzzing/fuzzer.go since I worked on this task and it might take me a while to get up to speed on those changes before I can resolve the conflicts.

These are possible scenarios that I can think of:
// ==============================================================
// Use case 1: Single init function with multiple target contracts
// Config:
fuzzer.config.Fuzzing.TargetContracts = ["ContractA", "ContractB", "ContractC"]
fuzzer.config.Fuzzing.TargetContractsInitFunctions = ["setUp"]
fuzzer.config.Fuzzing.UseInitFunctions = true

// Same can be achieved by passing enable-foundry-setup

// Result: initFunctions = ["setUp", "setUp", "setUp"]
// Actual calls: setUp called on all 3 contracts

// ================================================================
// Use case 2: Single "initialize" function with multiple contracts
// Config:
fuzzer.config.Fuzzing.TargetContracts = ["ContractA", "ContractB"]
fuzzer.config.Fuzzing.TargetContractsInitFunctions = ["initialize"]
fuzzer.config.Fuzzing.UseInitFunctions = true

// Result: initFunctions = ["initialize", "initialize"]
// Actual calls: initialize called on both contracts

// ================================================================
// Use case 3: Provided init functions for all contracts
// Config:
fuzzer.config.Fuzzing.TargetContracts = ["ContractA", "ContractB"]
fuzzer.config.Fuzzing.TargetContractsInitFunctions = ["setUp", "initialize"]
fuzzer.config.Fuzzing.UseInitFunctions = true

// Result: initFunctions = ["setUp", "initialize"]
// Actual calls: setUp on ContractA, initialize on ContractB

// ================================================================
// Use case 4: Multiple identical functions
// Config:
fuzzer.config.Fuzzing.TargetContracts = ["ContractA", "ContractB"]
fuzzer.config.Fuzzing.TargetContractsInitFunctions = ["setUp", "setUp"]
fuzzer.config.Fuzzing.UseInitFunctions = true

// Result: initFunctions = ["setUp", "setUp"]
// Actual calls: `setUp on both contracts

// ================================================================
// Use case 5: UseInitFunctions is false
// Config:
fuzzer.config.Fuzzing.TargetContracts = ["ContractA", "ContractB"]
fuzzer.config.Fuzzing.TargetContractsInitFunctions = ["setUp"]
fuzzer.config.Fuzzing.UseInitFunctions = false

// Result: initFunctions = ["", ""]
// Actual calls: No init functions called

// ================================================================
// Use case 6: Single empty string (edge case)
// Config:
fuzzer.config.Fuzzing.TargetContracts = ["ContractA", "ContractB"]
fuzzer.config.Fuzzing.TargetContractsInitFunctions = [""]
fuzzer.config.Fuzzing.UseInitFunctions = true

// Result: initFunctions = ["", ""]
// Actual calls: No init functions called (empty strings ignored)

@anishnaik
Copy link
Collaborator

Thanks for giving this a review @montyly! @0xZRA apologies for the massive delay. Will get this merged in the next few weeks.

@0xZRA
Copy link
Contributor Author

0xZRA commented Sep 30, 2025

Thanks for giving this a review @montyly! @0xZRA apologies for the massive delay. Will get this merged in the next few weeks.

@anishnaik are you still planning to look into this at some point?

@anishnaik
Copy link
Collaborator

Hey @0xZRA sorry sorry, medusa has taken a backseat for the past few months in terms of priorities. Will give this a look in the next week.

@anishnaik
Copy link
Collaborator

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +700 to +704
// Create and send the transaction
destAddr := contractAddr
msg := calls.NewCallMessage(fuzzer.deployer, &destAddr, 0, big.NewInt(0),
fuzzer.config.Fuzzing.BlockGasLimit, nil, nil, nil, callData)
msg.FillFromTestChainProperties(testChain)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P0 Badge Replace nonexistent BlockGasLimit config field

chainSetupFromCompilations builds the init-call transaction with fuzzer.config.Fuzzing.BlockGasLimit, but FuzzingConfig defines no such field (only TransactionGasLimit). The code will not compile because the struct has no BlockGasLimit member. This should use an existing gas limit value or add the missing field before merging.

Useful? React with 👍 / 👎.

Comment on lines +573 to +591
// Process target contracts init functions
targetContractsCount := len(fuzzer.config.Fuzzing.TargetContracts)
initConfigCount := len(fuzzer.config.Fuzzing.TargetContractsInitFunctions)

// Add initialization functions for target contracts
for i := 0; i < targetContractsCount; i++ {
initFunction := "" // Default: no initialization

if fuzzer.config.Fuzzing.UseInitFunctions {
if i < initConfigCount && fuzzer.config.Fuzzing.TargetContractsInitFunctions[i] != "" {
// Use explicit per-contract config
initFunction = fuzzer.config.Fuzzing.TargetContractsInitFunctions[i]
} else if len(fuzzer.config.Fuzzing.TargetContractsInitFunctions) == 1 {
// If only one init function specified (like "setUp") apply it to all contracts
initFunction = fuzzer.config.Fuzzing.TargetContractsInitFunctions[0]
}
}
initFunctions = append(initFunctions, initFunction)
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Align init functions to deployment order

The list of init functions is appended in the original TargetContracts order, but contracts are deployed in deploymentOrder when that list exists. When the order of deployments differs from the config array (e.g., because of library dependencies), initFunctions[i] will be applied to the wrong contract. This can cause init calls to target the wrong ABI or revert unnecessarily. Map functions by contract name or build initFunctions in the same order as contractsToDeploy.

Useful? React with 👍 / 👎.

@0xZRA
Copy link
Contributor Author

0xZRA commented Oct 23, 2025

Hey @0xZRA sorry sorry, medusa has taken a backseat for the past few months in terms of priorities. Will give this a look in the next week.

@anishnaik no worries! I'll review codex comments as soon as I can.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow Medusa to run init function (ex: setUp) once per fuzz run

5 participants